package edu.del.teamknowledgebase.service.code.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import edu.del.teamknowledgebase.common.exception.BusinessException;
import edu.del.teamknowledgebase.common.result.BusinessCode;
import edu.del.teamknowledgebase.service.code.CodeSendStrategy;
import edu.del.teamknowledgebase.service.code.CodeSendStrategyFactory;
import edu.del.teamknowledgebase.service.code.CodeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.regex.Pattern;

@Service
@RequiredArgsConstructor
@Slf4j
public class CodeServiceImpl implements CodeService {

    private final CodeSendStrategyFactory strategyFactory;

    private static final Pattern QQ_EMAIL_PATTERN = Pattern.compile("^[1-9]\\d{4,10}@qq\\.com$");
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");


    @Override
    public boolean sendVerificationCode(String receiver, String type, String scene) {
        // 1. 参数校验
        if (StrUtil.isBlank(receiver)) {
            throw new BusinessException(BusinessCode.PARAM_VALID_ERROR, "接收方不能为空");
        }

        if (StrUtil.isBlank(type)) {
            throw new BusinessException(BusinessCode.PARAM_VALID_ERROR, "验证码类型不能为空");
        }

        // 2. 格式校验
        switch (type) {
            case "email":
                if (!QQ_EMAIL_PATTERN.matcher(receiver).matches()) {
                    throw new BusinessException(BusinessCode.EMAIL_FORMAT_ERROR, "仅支持QQ邮箱，格式xxxxx@qq.com");
                }
                break;
            case "phone":
                if (!PHONE_PATTERN.matcher(receiver).matches()) {
                    throw new BusinessException(BusinessCode.PHONE_FORMAT_ERROR, "手机号格式错误");
                }
                break;
            default:
                throw new BusinessException(BusinessCode.PARAM_VALID_ERROR, "不支持的验证码类型");
        }

        // 3. 生成6位随机数
        String code = String.valueOf(RandomUtil.randomInt(300000, 999999));

        // 4. 获取对应策略并发送
        try {
            CodeSendStrategy strategy = strategyFactory.getStrategy(type);
            boolean success = strategy.sendCode(receiver, code);

            if (success) {
                log.info("验证码发送成功: receiver={}, type={}, scene={}", receiver, type, scene);
            } else {
                log.error("验证码发送失败: receiver={}, type={}, scene={}", receiver, type, scene);
                throw new BusinessException(BusinessCode.CODE_SEND_ERROR, "验证码发送失败");
            }

            return true;
        } catch (IllegalArgumentException e) {
            throw new BusinessException(BusinessCode.PARAM_VALID_ERROR, e.getMessage());
        }
    }
}
